﻿using System;
using System.Collections.Generic;
using System.IO;

namespace CabConfigProvisioning
{
    public class CabCopier : CabExtract
    {
        protected CabCreate _targetCab;

        private readonly List<MemoryFile> _files = new List<MemoryFile>();

        public CabCopier(FileInfo sourceCabFile, FileInfo targetCabFile) : base(sourceCabFile)
        {
            _targetCab = new CabCreate(targetCabFile);
        }

        protected override IntPtr OutputFileClose(FdiNotification fdin)
        {
            MemoryFile memoryFile;
            DecompressedFile file;
            if (_resources.TryGetValue(fdin.psz1, out file))
            {
                file.Found = true;
                file.Content = GcFile.Close(fdin.hf);
                if (!ProcessFile(file))
                    return (IntPtr) 0; // failure
                if(file.Content == null)
                    return (IntPtr) 1; // success
                memoryFile = MemoryCache.Instance.Put(new FileInfo(fdin.psz1), file.Content, fdin.date, fdin.time, fdin.attribs);
            }
            else
            {
                if(Matches(fdin.psz1))
                {
                    file = new DecompressedFile(fdin.psz1);
                    file.Content = GcFile.Close(fdin.hf);
                    if (_bProcessMatching && !ProcessFile(file))
                        return (IntPtr)0; // failure
                    if (file.Content == null)
                        return (IntPtr)1; // success
                    memoryFile = MemoryCache.Instance.Put(new FileInfo(fdin.psz1), file.Content, fdin.date, fdin.time, fdin.attribs);
                }
                else
                    memoryFile = MemoryCache.Instance.Put(new FileInfo(fdin.psz1), GcFile.Close(fdin.hf), fdin.date, fdin.time, fdin.attribs);
            }

            _files.Add(memoryFile);
            _targetCab.Add(memoryFile.FullName, fdin.psz1);

            if (_files.Count > 10)
            {
                _targetCab.FlushFolder();
                MemoryCache.Instance.RemoveAll(_files);
                _files.Clear();
            }
            return (IntPtr)1;   // success
        }


        public override void Dispose()
        {
            if(!_bDisposed)
            {
                _targetCab.FlushFolder();
                MemoryCache.Instance.RemoveAll(_files);
                _files.Clear();
                _targetCab.Dispose();
            }
        }
    }
}
